package com.xc.quickstart.common.bean;

import com.alibaba.fastjson.JSON;

import com.xc.quickstart.common.context.CommonContext;
import com.xc.quickstart.common.context.EnvironmentContext;
import com.xc.quickstart.common.event.ExceptionDelayQueueEvent;
import com.xc.quickstart.common.util.DateUtil;
import com.xc.quickstart.manager.wechat.WeChatManager;
import com.xc.quickstart.service.CrmAdminService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;

import java.util.*;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;

/**
 * @Author: yinyansheng
 */
@Slf4j
public class ExceptionDelayQueueProcessor {

    @Autowired
    private WeChatManager weChatManager;

    @Autowired
    private CrmAdminService crmAdminService;

    @Autowired
    private Environment env;

    private final static Set<String> ENVIRONMENT_SET = new HashSet<String>() {{
        add(EnvironmentContext.STAGE);
        add(EnvironmentContext.PROD);
    }};

    private volatile boolean consume = false;

    private DelayQueue<ExceptionDelayQueueEvent> delayQueue = new DelayQueue<>();
    private Map<String, ExceptionDelayQueueEvent> delayQueueMap = new HashMap<>();

    private final ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1,
            new BasicThreadFactory.Builder().namingPattern("crm-schedule-pool-%d").daemon(true).build());

    public DelayQueue<ExceptionDelayQueueEvent> getDelayQueue() {
        return delayQueue;
    }

    public synchronized void put(ExceptionDelayQueueEvent event) {
        if (null == event.getAlarmCount()) {
            event.setAlarmCount(1);
        }

        if (delayQueueMap.containsKey(event.getClassName())) {
            log.info("[异常告警延迟队列]删除,{}", JSON.toJSONString(event));

            ExceptionDelayQueueEvent value = delayQueueMap.get(event.getClassName());

            event.setAlarmCount(value.getAlarmCount() + 1);
            delayQueue.remove(event);
        }

        log.info("[异常告警延迟队列]加入,{},alarmTime:{}", JSON.toJSONString(event), DateUtil.format(new Date(event.getAlarmTime()), CommonContext.YYYY_MM_DD_HH_MM_SS));
        delayQueueMap.put(event.getClassName(), event);
        delayQueue.put(event);
    }

    public synchronized void consume() {
        if (!consume) {
            log.info("[异常告警延迟队列]消费开始.....");
            executorService.execute(() -> {
                while (true) {
                    try {
                        ExceptionDelayQueueEvent delayEvent = delayQueue.take();
                        log.info("[异常告警延迟队列]消费,{}", JSON.toJSONString(delayEvent));

                        if (ENVIRONMENT_SET.contains(env.getProperty("spring.profiles.active"))) {
                            String msg = String.format("【%s】\n 类名：【%s】\n 时间区间：【10】分钟 \n 错误阀值：【%d】次 \n 错误信息：%s",
                                    delayEvent.getTitle(),
                                    delayEvent.getClassName(),
                                    delayEvent.getAlarmCount(),
                                    delayEvent.getMsg());
                            Set<String> jobNumberSet = crmAdminService.listSendWeChatJobNumber();
                            weChatManager.send(jobNumberSet, msg);
                        }

                        delayQueueMap.remove(delayEvent.getClassName());
                        log.info("[异常告警延迟队列]消费结束,{}", JSON.toJSONString(delayEvent));
                    } catch (InterruptedException ie) {
                        log.error("[异常告警延迟队列]消费中断....,ex:{}", ExceptionUtils.getStackTrace(ie));
                        break;
                    }
                }
            });
            consume = true;
        }
    }
}
